<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>在线聊天</title>
    <script src="http://47.106.66.89:8080/js/vue.min.js"></script>
    <script src="http://47.106.66.89:8080/js/axios.min.js"></script>
    <script src="js/login.js"></script>
    <link  href="http://47.106.66.89:8080/js/ele-2.15.7/theme-chalk/index.css" rel="stylesheet">
    <script src="http://47.106.66.89:8080/js/ele-2.15.7/index.js"></script>
    <script src="/auth/js/auth.js"></script>
</head>
<body>
<div id="app" style="height: 100%">
    <header class="p900 flexbtw">
        <h3>在线聊天、在线客服</h3>
        <div>
            <login ref="login"></login>
        </div>
    </header>
    <main class="m900 flexbtw" style="height: calc(100% - 75px)">
        <aside>
            <div v-for="u in onlines" @click="receiver=receiver==u?null:u"
                 :style="{backgroundColor: receiver==u?'#888':'#8c939d'}">{{u.name}}</div>
        </aside>
        <article>
            <div id="msgs">
                <div v-for="m in msgs" :class="m.sender.uid==myinfo.uid?'send':'recv'">
                    <label class="user">{{m.sender.name}}</label>
                    <span class="msg" v-if="m.type=='text'">{{m.content}}</span>
                    <img v-else-if="m.type=='image'" :src="m.content"
                         style="width: 200px;">
                </div>
            </div>
            <textarea :disabled="ws == null" v-model="msg" placeholder="Ctrl + Center 发送" id="msg"
                    @paste="pasteImage"></textarea>
            <div id="ops">
                <input :disabled="ws != null" placeholder="用户名" v-model="myinfo.uid">
                <button :disabled="ws != null" @click="login">登录</button>
                <button :disabled="ws == null" @click="send">发送</button>
            </div>
        </article>
    </main>
    <footer>源辰公司</footer>
</div>
<script>
    let v = new Vue({
        el: "#app",
        data: {
            // WebSocket对象
            ws: null,
            // 当前用户
            myinfo: {uid:""},
            // 在线用户
            onlines: [],
            // 消息列表
            msgs: [],
            msg:"",
            receiver: null
        },
        methods: {
            login(uid){
                if(uid){
                    this.myinfo.uid = uid;
                }
                if(!this.myinfo.uid){
                    this.$message.error("请输入用户名");
                    return;
                }
                this.ws = new WebSocket("ws://127.0.0.1/talk/" + this.myinfo.uid);
                this.ws.onopen = () => {
                    this.$message.success("登录成功");
                }
                this.ws.onclose = () => {
                    this.$message.success("连接关闭");
                    this.ws = null;
                }
                this.ws.onmessage = (e) => {
                    let msg = e.data = JSON.parse(e.data);
                    if (msg.type === 'upline') {
                        this.onlines.push(msg.sender);
                        // 判断发送者uid 是否等于当前用户uid
                        if (msg.sender.uid == this.myinfo.uid) {
                            // 更新用户信息
                            this.myinfo = msg.sender;
                        }
                    } else if (msg.type === 'downline') {
                        this.onlines = this.onlines.filter(u=>u.uid != msg.sender.uid);
                    } else if (msg.type === 'allOnlineUsers') {
                        let allOnlineUsers = JSON.parse(msg.content);
                        allOnlineUsers.forEach(u=>{
                            this.onlines.push(u);
                        });
                        return;
                    }
                    this.msgs.push(msg);
                }
            },
            send(){
                // 私发消息, 直接加入到消息列表
                if(this.receiver != null){
                    this.msgs.push({
                        sender: this.myinfo,
                        receiver: this.receiver,
                        content: this.msg
                    })
                }
                this.ws.send(JSON.stringify({
                    type:"text",
                    content:this.msg,
                    sender:this.myinfo,
                    receiver:this.receiver,
                }));
                this.msg = "";
            },
            pasteImage(e){
                var clipboard = e.clipboardData;
                if (clipboard.items[0].type.match(/image/)) {
                    let fd = new FormData();
                    // 从剪贴板提取图片二级制数据
                    let blob = clipboard.items[0].getAsFile();
                    let nm = "image.jpg"
                    fd.append("abc",blob,nm);
                    axios.post("/user/upload",fd).then(res=>{
                        if(res.data.code == 1){
                            // 私发消息, 直接加入到消息列表
                            if(this.receiver != null){
                                this.msgs.push({
                                    sender: this.myinfo,
                                    receiver: this.receiver,
                                    content: this.msg
                                })
                            }
                            this.ws.send(JSON.stringify({
                                type:"image",
                                content: "/user" + res.data.data,
                                sender:this.myinfo,
                                receiver:this.receiver,
                            }));
                        }
                    });
                }
            }

        }
    });
</script>
</body>
</html>



















































<style>
    * {
        padding: 0px;
        margin: 0px;
        font-family: "Arial", "Microsoft YaHei", "黑体", "宋体", sans-serif;
    }

    html,body{
        height: 100%;
    }
    body{
        display: flex;
        flex-direction: column;
    }

    a {
        text-decoration: none;
    }

    button{
        padding: 3px 10px;
    }

    .p900 {
        padding: 0px calc((100% - 900px) / 2);
    }

    .m900 {
        width: 900px;
        margin: 0px auto;
    }

    .flexbtw {
        display: flex;
        justify-content: space-between;
        align-items: center;
    }

    header {
        background-color: #eee;
        flex: none;
    }
    header>h3{
        margin: 10px 0px;
    }

    main {
        flex: auto;
        background-color: #ddd;
    }

    footer {
        flex: none;
        padding: 5px;
        text-align: center;
        background-color: #eee;
    }

    aside {
        width: 200px;
        height: 100%;
        background-color: #ccc;
        flex: none;
    }

    article {
        height: 100%;
        flex: auto;
    }

    article {
        display: flex;
        flex-direction: column;
    }

    #msgs {
        flex: auto;
        box-sizing: border-box;
        padding: 10px;
    }

    #msg {
        flex: none;
        width: 100%;
        height: 100px;
        box-sizing: border-box;
    }

    .send > * {
        float: right;
    }

    .recv > * {
        float: left;
    }

    .send, .recv {
        clear: both;
        padding: 5px 0px;
    }

    .user, .msg {
        padding: 5px;
    }

    .msg {
        background-color: #e9e9e9;
        border-radius: 3px;
    }

    aside>div{
        text-align: center;
        padding: 10px;
        margin: 3px;
        background-color:#8c939d;
    }

    aside>div:hover{
        background-color:#8c939d55;
        cursor: pointer;
    }

    #ops{
        text-align: right;
        padding: 7px;
    }
    #ops>*{
        box-sizing: border-box;
        height: 25px;
        vertical-align: middle;
        margin: 0px 5px;
        text-align: center;
    }
    textarea{
        padding: 3px;
    }
</style>